package com.qut.graduate.busrtquery.view;

import android.animation.Animator;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Matrix;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;

@SuppressLint("AppCompatCustomView")
public class AutoZoomInImageView extends ImageView {
    private int mDrawableW;
    private int mDrawableH;
    private int mImageViewW;
    private int mImageViewH;
    private long mDurationMillis = 700;
    private float[] mValues = new float[9];
    private float mScaleDelta = 0.2f;
    private Drawable mDrawable;
    private Matrix mMatrix;

    public AutoZoomInImageView(Context context) {
        super(context);
        this.setScaleType(ScaleType.MATRIX);
    }

    public AutoZoomInImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.setScaleType(ScaleType.MATRIX);
    }

    public AutoZoomInImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        this.setScaleType(ScaleType.MATRIX);
    }

    public AutoZoomInImageView init() {
        initInternalValues();
        initPicturePosition();
        return this;
    }

    public void init(Drawable drawable) {
        initInternalValues(drawable);
        initPicturePosition();
    }

    private void initInternalValues() {
        mDrawable = getDrawable();
        if (mDrawable == null)
            throw new IllegalArgumentException("请设置AutoZoomInImageView的资源图片");
        mDrawableW = mDrawable.getIntrinsicWidth();
        mDrawableH = mDrawable.getIntrinsicHeight();
        mImageViewW = getMeasuredWidth();
        mImageViewH = getMeasuredHeight();
        mMatrix = getImageMatrix();
        mMatrix.getValues(mValues);
    }

    private void initInternalValues(Drawable drawable) {
        mDrawable = drawable;
        if (mDrawable == null)
            throw new IllegalArgumentException("请设置AutoZoomInImageView的资源图片");
        mDrawableW = mDrawable.getIntrinsicWidth();
        mDrawableH = mDrawable.getIntrinsicHeight();
        mImageViewW = getMeasuredWidth();
        mImageViewH = getMeasuredHeight();
        mMatrix = getImageMatrix();
        mMatrix.getValues(mValues);
    }

    private void initPicturePosition() {
        updateMatrixValuesOrigin(mMatrix, mValues, mDrawableW, mDrawableH, mImageViewW, mImageViewH);
        setImageMatrix(mMatrix);
    }

    private void startZoomInByScaleDelta(final float scaleDelta, long duration) {
        final float oriScaleX = mValues[0];
        final float oriScaleY = mValues[4];
        ValueAnimator va = ValueAnimator.ofFloat(0, scaleDelta);
        va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float value = (Float) animation.getAnimatedValue();
                if (mOnZoomListener != null)
                    mOnZoomListener.onUpdate(AutoZoomInImageView.this, value / scaleDelta);
                updateMatrixValuesSpan(mValues, mDrawableW, mDrawableH, mImageViewW, mImageViewH,
                        oriScaleX, oriScaleY, value);
                mMatrix.setValues(mValues);
                setImageMatrix(mMatrix);
            }
        });
        va.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
                if (mOnZoomListener != null) mOnZoomListener.onStart(AutoZoomInImageView.this);
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                if (mOnZoomListener != null) mOnZoomListener.onEnd(AutoZoomInImageView.this);
            }

            @Override
            public void onAnimationCancel(Animator animation) {
            }

            @Override
            public void onAnimationRepeat(Animator animation) {
            }
        });
        va.setDuration(duration);
        va.start();
    }

    /**
     * 开始缩放
     *
     * @param scaleDelta     图像将根据原始比例缩放的比例
     * @param durationMillis 缩放的持续时间，单位为毫秒
     * @param delayMillis    启动缩放动画的延迟时间（毫秒）
     */
    public void startZoomInByScaleDeltaAndDuration(final float scaleDelta, final long durationMillis, long delayMillis) {
        if (scaleDelta < 0)
            throw new IllegalArgumentException("scaledelta应大于0，现在scaledelta为：" + scaleDelta);
        if (durationMillis < 0)
            throw new IllegalArgumentException("durationMillis不应小于0，现在durationMillis为：" + durationMillis);
        if (delayMillis < 0)
            throw new IllegalArgumentException("DelayMillis不应小于0，现在DelayMillis为：" + delayMillis);
        postDelayed(new Runnable() {
            @Override
            public void run() {
                startZoomInByScaleDelta(scaleDelta, durationMillis);
            }
        }, delayMillis);
    }

    /**
     * 图像将根据原始比例缩放的比例
     *
     * @param scaleDelta
     * @return
     */
    public AutoZoomInImageView setScaleDelta(float scaleDelta) {
        mScaleDelta = scaleDelta;
        return this;
    }

    /**
     * 缩放的持续时间，单位为毫秒
     *
     * @param durationMillis
     * @return
     */
    public AutoZoomInImageView setDurationMillis(long durationMillis) {
        mDurationMillis = durationMillis;
        return this;
    }

    /**
     * 回调的时候同时完成动画
     *
     * @param onZoomListener
     * @return
     */
    public AutoZoomInImageView setOnZoomListener(OnZoomListener onZoomListener) {
        mOnZoomListener = onZoomListener;
        return this;
    }

    /**
     * 开始缩放动画
     *
     * @param delayMillis 启动缩放动画的延迟时间（毫秒）。
     */
    public void start(long delayMillis) {
        postDelayed(new Runnable() {
            @Override
            public void run() {
                startZoomInByScaleDelta(mScaleDelta, mDurationMillis);
            }
        }, delayMillis);
    }

    private void updateMatrixValuesOrigin(Matrix outMatrix, float[] outValues, float drawW, float drawH, float imageW, float imageH) {
        if (outMatrix == null || outValues == null) {
            throw new IllegalArgumentException("请设置AutoZoomInImageView矩阵和值的源");
        }
        outMatrix.reset();
        if ((imageH * drawW > drawH * imageW)) {
            float scale1 = (imageH) / (drawH);
            float offset1 = (drawW * scale1 - imageW) / 2;
            outMatrix.postScale(scale1, scale1);
            outMatrix.postTranslate(-offset1, 0);
        } else {
            float scale2 = (imageW) / (drawW);
            float offset2 = (drawH * scale2 - imageH) / 2;
            outMatrix.postScale(scale2, scale2);
            outMatrix.postTranslate(0, -offset2);
        }
        outMatrix.getValues(outValues);
    }

    private void updateMatrixValuesSpan(float[] outValues, float drawW, float drawH, float imageW, float imageH,
                                        float oriScaleX, float oriScaleY, float scaleDelta) {
        outValues[0] = oriScaleX * (1 + scaleDelta);
        outValues[4] = oriScaleY * (1 + scaleDelta);
        float offsetwidth = (drawW * outValues[0] - imageW) / 2;
        outValues[2] = -offsetwidth;
        float offsetHeight = (drawH * outValues[4] - imageH) / 2;
        outValues[5] = -offsetHeight;
    }

    private OnZoomListener mOnZoomListener;

    public interface OnZoomListener {
        /**
         * 放大动画更新时回调
         *
         * @param view     自动缩放图像视图
         * @param progress 返回动画进度，范围为[0,1]
         */
        void onUpdate(View view, float progress);

        void onEnd(View view);

        void onStart(View view);
    }

}